package com.example.demo.udp;

import com.example.demo.util.CommandEnum;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.DatagramPacket;
import io.netty.channel.socket.nio.NioDatagramChannel;
import lombok.extern.slf4j.Slf4j;

import java.net.InetSocketAddress;

/**
 * @Description: UDP netty 客户端
 * @Author: junqiang.lu
 * @Date: 2023/8/25
 */
@Slf4j
public class DemoUdpNettyClient {

    private final String serverHost;

    private final int serverPort;

    private final int clientPort;

    private final EventLoopGroup mainGroup;

    private final Bootstrap bootstrap;

    private Channel channel;


    public DemoUdpNettyClient(String serverHost, int serverPort, int clientPort) {
        this.serverHost = serverHost;
        this.serverPort = serverPort;
        this.clientPort = clientPort;
        this.mainGroup = new NioEventLoopGroup();
        this.bootstrap = new Bootstrap();

    }

    public Channel getChannel() {
        return this.channel;
    }

    /**
     * 创建连接
     */
    public void connect() throws InterruptedException {
        bootstrap.group(mainGroup)
                .channel(NioDatagramChannel.class)
                .option(ChannelOption.SO_BROADCAST, true)
                .option(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(65535))
                .option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
                .localAddress(clientPort)
                .handler(new DemoUdpNettyClientHandler());
        ChannelFuture future = bootstrap.bind().sync();
        this.channel = future.channel();
    }

    /**
     * 发送消息
     *
     * @param message
     */
    public void sendMessage(String message, String device) {
        log.info("客户端待发送消息:{}", message);
        Channel channel = this.getChannel();
        byte[] resBytes = message.getBytes();
        //ping和组网
        if (device.equals(CommandEnum.ALL.getCommandName())
                || device.equals(CommandEnum.ZUWANG.getCommandName())) {
            DatagramPacket sendPacket = new DatagramPacket(Unpooled.copiedBuffer(resBytes)
                    , new InetSocketAddress(serverHost, serverPort));
            channel.writeAndFlush(sendPacket);
            return;
        }
//        DatagramPacket sendPacket = new DatagramPacket(Unpooled.copiedBuffer(resBytes)
//                , new InetSocketAddress(serverHost, serverPort));
//        channel.writeAndFlush(sendPacket);
        //读取参数  自检测 自修复 都是针对ip发
        String ip = DemoUdpNettyServerHandler.senderMap.get(device).getIp();

        DatagramPacket sendPacket = new DatagramPacket(Unpooled.copiedBuffer(resBytes)
                , new InetSocketAddress(ip, serverPort));
        channel.writeAndFlush(sendPacket);
    }

    public void close() throws InterruptedException {
        log.info("关闭客户端");
        mainGroup.shutdownGracefully();
    }


}

